/*
 * $Id: BaseDAO.java,v 1.18 2009/10/27 13:45:30 navdeep_mahajan Exp $
 * 
 * Copyright (C) 2006 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.common.database.dao;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.Session;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.ASCUtil;

/**
 * @author 212042764
 * 
 */
public class BaseDAO extends HibernateDaoSupport implements IBaseDAO {
	/**
	 * Eclispe generated
	 */
	private static final long serialVersionUID = 5269086193618854204L;
	private String tableName = null;

	protected BaseDAO(String tableName) {
		this.tableName = tableName;
	}

	public List<?> findByProperty(String propertyName, Object value) {
		String queryString = "from " + tableName + " where " + propertyName
				+ "= ?";
		ASCLogger.debug(this.getClass(), "findByProperty", new StringBuffer()
				.append("Ruuning where clause using query ")
				.append(queryString));
		return getHibernateTemplate().find(queryString, value);
	}

	public List<?> findByProperty(String propertyName, Object value,
			String orderBy) {
		String queryString = "from " + tableName + " where " + propertyName
				+ "= ? order by " + orderBy + " asc";
		ASCLogger.debug(this.getClass(), "findByProperty", new StringBuffer()
				.append("Ruuning where clause using query ")
				.append(queryString));
		return getHibernateTemplate().find(queryString, new Object[] { value });
	}

	public List<?> findByProperties(Map<String, Object> whereClause) {
		if (ASCUtil.isNullOrEmptyMap(whereClause)) {
			return null;
		}
		StringBuffer queryString = new StringBuffer().append("from ").append(
				tableName).append(" where ");
		Iterator<String> properties = whereClause.keySet().iterator();
		boolean firstRun = true;
		while (properties.hasNext()) {
			if (firstRun) {
				firstRun = false;
			} else {
				queryString.append(" and ");
			}
			String propertyName = properties.next();
			queryString.append(propertyName).append("= ? ");
		}
		Object[] values = whereClause.values().toArray();
		return getHibernateTemplate().find(queryString.toString(), values);
	}

	public Object findObjectByID(String propertyName, Object value) {
		List<?> lstObject = findByProperty(propertyName, value);
		Object retVal = null;
		if (!ASCUtil.isNullOrEmptyList(lstObject)) {
			retVal = lstObject.get(0);
		}
		return retVal;

	}

	public void deleteByProperty(String propertyName, Object value) {
		deleteByProperty(propertyName, value, this.tableName);
	}

	public void deleteByProperty(String propertyName, Object value,
			String tableName) {
		StringBuffer query = new StringBuffer("delete from ");
		query.append(tableName).append(" where ");
		query.append(propertyName).append(" = :value");
		StringBuffer msg = new StringBuffer().append("query: ").append(query);

		Session s = getHibernateTemplate().getSessionFactory().openSession();
		//Removed transaction block as we can't commit in XA block
		// Transaction tx = s.beginTransaction();
		int deleteCount = 0;
		try {
			deleteCount = s.createQuery(query.toString()).setString("value",
					value.toString()).executeUpdate();
			// tx.commit();
			msg.append(" Deleted: ").append(deleteCount);

		} catch (RuntimeException e) {
			// tx.rollback();
			msg.append(" Delete Failed: ").append(e.getMessage());
			ASCLogger.error(this.getClass(), "deleteByProperty", msg);
			throw e;
		} finally {
			s.close();
		}
		ASCLogger.info(this.getClass(), "deleteByProperty", msg);

	}

	public void save(Object pojo) {
		getHibernateTemplate().saveOrUpdate(pojo);
	}

	public void deleteByID(Object pojo) {
		getHibernateTemplate().delete(pojo);
	}

	public void refreshCache() {
		// Refresh the cache if it is configured. Otherwise it will do nothing.
		ASCLogger.info(this.getClass(), "refreshCache", "Refresh cache..");
	}

	public void refresh(Object pojo) {
		getHibernateTemplate().refresh(pojo);
	}

	protected StringBuffer initQuery(String tableName) {
		StringBuffer query = new StringBuffer();
		query.append("from ").append(tableName);
		return query;
	}

	protected StringBuffer initQuery() {
		return initQuery(this.tableName);
	}
}
